#include <iostream>
#include <vector>
#include <cstdlib>
#include <unistd.h>
#include <string>
#include <sys/types.h>
#include <sys/wait.h>



struct channel
{
    channel(int fd , pid_t slaverid , std::string name)
    :wfd_(fd) , slaverid_(slaverid) , process_name_(name)
    {}

    int wfd_;
    pid_t slaverid_;
    std::string process_name_;
};


class process_poll
{

    void slaver()
    {
        char buffer[1024];
        while(1)
        {
            buffer[0] = 0;
            int n = read(0 , buffer , sizeof(buffer));
            buffer[n] = 0;
            int i = 0 , x = 0 , y = 0;
            std::cout << " " << getpid() << " get a message : " << buffer;
            while(i < n && isdigit(buffer[i])) x = x*10 + buffer[i++] - '0';
            while(i < n && isspace(buffer[i])) i++;
            while(i < n && isdigit(buffer[i])) y = y*10 + buffer[i++] - '0';
            std::cout << " , the answer is : " << x + y << std::endl; \
        }
    }

public:
    process_poll(int sz = 3)
        :sz_(sz), isrunning_(false)
    {}

   int Run()
   {
       // 启动线程池, 创建sz个线程
       for(int i = 0 ; i < sz_ ; i++)
       {
           int fd[2] = {};
           int n =  pipe(fd);
           if(n < 0) return -1;
           
           pid_t id = fork();
           if(id == 0)
           {
               dup2(fd[0] , 0);
               close(fd[1]);
               slaver(); 
           }
           close(fd[0]);
           std::string name = "process" + std::to_string(i + 1);
           channel tmp(fd[1] , id , name);
           channels.push_back(tmp);
           sleep(1);
       }
   }

   size_t size()
   {
        return sz_;
   }

   int operator[](int n)
   {
        return channels[n].wfd_;
   }

    ~process_poll()
    {
        for(auto& ch: channels) close(ch.wfd_);
        for(auto& ch: channels) waitpid(ch.slaverid_ , nullptr , 0);
    }

private:
    std::vector<channel> channels;  // 用来存储每个进程的信息
    int sz_;
};
